package mx.itesm.twritter.server;

import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import mx.itesm.twritter.server.map.AStar;
import mx.itesm.twritter.server.map.OSMParser;
import mx.itesm.twritter.server.ontology.Ontology;
import mx.itesm.twritter.server.parser.ParsedTweet;
import mx.itesm.twritter.server.parser.ProcessedTweet;
import mx.itesm.twritter.shared.ToDraw;
import mx.itesm.twritter.shared.Tweet;
import mx.itesm.twritter.shared.map.Node;
import mx.itesm.twritter.client.ParsingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class ParsingServiceImpl extends RemoteServiceServlet implements
		ParsingService {
	
	public static OSMParser map = new OSMParser("../src/mx/itesm/twritter/server/PyOSMRoute/map.osm");
	public static Ontology o = new Ontology();
	public AStar astar;
	public int tipo;
	
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		this.astar = new AStar();
	}
	
	@Override
	public ToDraw parse(int i, Tweet input) throws IllegalArgumentException,
			Exception {
		ToDraw toDraw = new ToDraw();
		
		toDraw.setAutor(input.getUser());
		toDraw.setText(input.getText());
		toDraw.setHora(input.getCreatedAt());
		
		List<Node> nodes = new LinkedList<Node>();
		
		if(!input.getUser().equalsIgnoreCase("FonzTraffic")) {
			toDraw.setRoute(nodes);
			return toDraw;
		}
		
		//System.err.println("Tweet: " + input.getText());
		
		/** Aqui se parsea el tweet, se pasa al A* y se regresan los nodos para que 
		 *  el cliente lo dibuje
		 */
		ParsedTweet t = new ParsedTweet();
		t.tipo = i;
		t = ParsedTweet.createParsedTweet(input.getText(), input.getId(), input.getCreatedAt());
		
		if(t == null) {
			toDraw.setCrossings("No se pudo parsear el tweet");
			return toDraw;
		}
		
		toDraw.setParsed("Sobre: " + t.getRoute() + "\n" +
						 "Desde: " + t.getFrom()  + "\n" +
						 "Hasta: " + t.getTo()  + "\n" +
						 "VelText: " + t.getVelocityText());
		
		toDraw.setVelocity(t.getVelocity());
		toDraw.setVelocityText(t.getVelocityText());
		
		toDraw.setProcessed("Search sobre: " + o.searchRoute(t.getRoute()) + "\n" + 
							"Search desde: " + o.searchRoute(t.getFrom()) + "\n" +
							"Search hasta: " + o.searchRoute(t.getTo()));
		
		
		if(t != null) {
			if (o.searchRoute(t.getRoute()) != null && o.searchRoute(t.getFrom()) != null && o.searchRoute(t.getTo()) != null) {
				
				ProcessedTweet p = new ProcessedTweet(o.searchRoute(t.getRoute()),o.searchRoute(t.getFrom()),o.searchRoute(t.getTo()), t.getVelocity());
				
				try {
					System.err.println("llamando A*");
					System.err.println("FromID: " + map.findSegment(p).get(0).getId());
					System.err.println("ToID:   " + map.findSegment(p).get(1).getId());
					
					int idStart = map.findSegment(p).get(0).getId();
					int idEnd =  map.findSegment(p).get(1).getId();
					
					nodes = astar.route(idStart, idEnd);
				} catch (Exception e) {
					e.printStackTrace();
					System.err.println("Error: " + e.getMessage());
					toDraw.setCrossings(e.getMessage());
				}
				
			} else {
				
				//System.err.println("No se encontraron cruces...");
			}
		}
		
		System.err.println(nodes);
		
		toDraw.setRoute(nodes);
		
		return toDraw;
	}
	
	public ToDraw parse(Tweet input) throws Exception {
		
		ToDraw toDraw = new ToDraw();
		
		toDraw.setAutor(input.getUser());
		toDraw.setText(input.getText());
		toDraw.setHora(input.getCreatedAt());
		
		List<Node> nodes = new LinkedList<Node>();
		
		if(!input.getUser().equalsIgnoreCase("FonzTraffic")) {
			toDraw.setRoute(nodes);
			return toDraw;
		}
		
		//System.err.println("Tweet: " + input.getText());
		
		/** Aqui se parsea el tweet, se pasa al A* y se regresan los nodos para que 
		 *  el cliente lo dibuje
		 */
		ParsedTweet t = ParsedTweet.createParsedTweet(input.getText(), input.getId(), input.getCreatedAt());
		
		if(t == null) {
			toDraw.setCrossings("No se pudo parsear el tweet");
			return toDraw;
		}
		
		toDraw.setParsed("Sobre: " + t.getRoute() + "\n" +
						 "Desde: " + t.getFrom()  + "\n" +
						 "Hasta: " + t.getTo() );
		
		toDraw.setVelocity(t.getVelocity());
		
		toDraw.setProcessed("Search sobre: " + o.searchRoute(t.getRoute()) + "\n" + 
							"Search desde: " + o.searchRoute(t.getFrom()) + "\n" +
							"Search hasta: " + o.searchRoute(t.getTo()));
		
		
		if(t != null) {
			if (o.searchRoute(t.getRoute()) != null && o.searchRoute(t.getFrom()) != null && o.searchRoute(t.getTo()) != null) {
				
				ProcessedTweet p = new ProcessedTweet(o.searchRoute(t.getRoute()),o.searchRoute(t.getFrom()),o.searchRoute(t.getTo()), t.getVelocity());
				
				try {
					System.err.println("llamando A*");
					System.err.println("FromID: " + map.findSegment(p).get(0).getId());
					System.err.println("ToID:   " + map.findSegment(p).get(1).getId());
					
					int idStart = map.findSegment(p).get(0).getId();
					int idEnd =  map.findSegment(p).get(1).getId();
					
					nodes = astar.route(idStart, idEnd);
				} catch (Exception e) {
					e.printStackTrace();
					System.err.println("Error: " + e.getMessage());
					toDraw.setCrossings(e.getMessage());
				}
				
			} else {
				
				//System.err.println("No se encontraron cruces...");
			}
		}
		
		System.err.println(nodes);
		
		toDraw.setRoute(nodes);
		
		return toDraw;
	}


}
